package models.security;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import framework.base.BaseModel;
import framework.utils.ArrayUtil;
import framework.utils.DicUtil;
import framework.utils.StringUtil;
import models.security.utils.SecurityConstant;
import play.data.validation.Check;
import play.data.validation.CheckWith;
import play.data.validation.Equals;
import play.data.validation.MaxSize;
import play.data.validation.Required;
@Entity
@Table(name="T_USER")
public class User extends BaseModel {
    //姓名
    @Required(message="姓名不能为空")
    @MaxSize(value=16,message="姓名不能超过16个字符")
    public String name;
    //登录名
    @Required(message="用户名不能为空")
    @CheckWith(value=UserNameUniqueCheck.class,message="用户名已存在")
    @MaxSize(value=32,message="用户名不能超过32个字符")
    public String userName;
    //密码
    @Required(message="密码不能为空")
    @MaxSize(value=64,message="密码不能超过64个字符")
    public String password;
    @Transient
    @Required(message="确认密码不能为空")
    @Equals(value="password",message="密码不一致")
    public String confirmPassword;
    //上次登录时间
    public Date lastLoginAt;
    //上次登录IP
    public String lastLoginIp;
    //本次登录时间
    public Date loginAt;
    //本次登录IP
    public String loginIp;
    //密钥
    public String securityKey;
    
    @ManyToMany(cascade=CascadeType.PERSIST,fetch=FetchType.LAZY)
    @JoinTable(name="T_USER_ROLE")
    public List<Role> roles = new ArrayList<Role>();
    
    
    public User(){
        this.createdAt = new Date();
        this.updatedAt = new Date();
        this.status=1;
    }
    
    public User(String name,String userName){
        this();
        this.name = name;
        this.userName = userName;
    }
    
    static class UserNameUniqueCheck extends Check{
        @Override
        public boolean isSatisfied(Object user, Object value) {
            boolean rcode = false;
            User  u = null;
            if(user instanceof User){
                 u = (User) user;
            }
            if(null!=u){
                User obj = User.findByUserName(value.toString());
                if(null==obj || obj.id.equals(u.id)){
                    rcode = true;
                }
            }
            return rcode;
        }
    }
    
    
    /**
     * 分配角色
     * @param rids
     */
    public void assignRoles(String[] rids){
        Set<Role> roles = new HashSet<Role>();
        if(!ArrayUtil.isEmpty(rids)){
            for(int i=0;i<rids.length;i++){
                if(!StringUtil.isBlank(rids[i])){
                    Role r = Role.findById(rids[i]);
                    if(null!=r){
                        roles.add(r);
                    }
                }
            }
        }
        this.roles.clear();
        this.roles.addAll(roles);
    }
    
    public String roleNames(){
        StringBuffer sb = new StringBuffer();
        if(null!=roles && !roles.isEmpty()){
            for(Role role : roles){
                if(StringUtil.isBlank(sb.toString())){
                   sb.append(role.name); 
                }else{
                    sb.append(","+role.name);
                }
            }
        }
        return sb.toString();
    }
    
    public void revoke(){
        this.roles.clear();
        this.save();
    }
    
    
    public static User findByUserName(String userName){
        String sql="from User a where a.userName=? and a.status=?";
        return User.find(sql, userName,USE_STATUS).first();
    }
    
    
    /**
     * 获取当前用户所有的权限信息
     * @return
     */
    public Map<String,String> allPermissions(){
        List<Role> roles = this.roles;
        Set<Permission> permissions = new LinkedHashSet<Permission>();
        if(null!=roles){
            for(Role role : roles){
                if(role.isActive()){
                    permissions.addAll(role.permissions);
                }
            }
        }       
        Map<String,String> result = Permission.initResource(permissions);
        return result;
    }
    
    
    public void login(String ip){
        this.lastLoginAt = this.loginAt;
        this.lastLoginIp = this.loginIp;
        this.loginAt = new Date();
        this.loginIp = ip;
        this.save();
    }
    
}
